#ifndef __UDF07_PROCESS_C_
#define __UDF07_PROCESS_C_

#include "udf_global.h"

#if( UDF_EN_13 > 0 ) || ( UDF03_ROM_FUNCTION2 == 1 )

static void udsf_udf07_handle(void) __attribute__((unused));

#include "../udsf/udsf_uart.c"
#include "../udsf/udsf_spi.c"
#include "../udsf/udsf_delay.c"
#include "../udsf/udsf_protocol.c"
#include "../udsf/udsf_lpw.c"
#include "../udsf/udsf_dbscan.c"
#include "../udsf/udsf_data_send.c"
#include "../udsf/udsf_gpio.c"
#include "../udsf/udsf_udf_switch.c"

/*udf07 callback*/
static void udsf_udf07_handle(void)
{
//	STRUCT_POINTRST *frameRst = (STRUCT_POINTRST *)(paramALG->framePackAddr);
	
	/*调试数据输出*/
	#ifdef DEBUG_DATA_ENABLE
	struct frame_struct debug_frame_ctrl;
	{	
		int temp = paramRSV->frame_interval;
		if( temp > 127*10 ){
			debug_frame_ctrl.frame_info.interval_10_100_ms = temp/100 + 0x80;
		}else{
			debug_frame_ctrl.frame_info.interval_10_100_ms = temp/10 ;
		}
		debug_frame_ctrl.Proto_MVersion = DEBUG_DATA_PROTOCOL_VER;
		#if DEBUG_DATA_INTERFACE == 1
			#if DEBUG_DATA_PROTOCOL_VER > 1
			
			debug_frame_ctrl.send_data  = udsf_spi_send_data_trans;
			debug_frame_ctrl.send_frame = udsf_spi_send_data;
			#elif DEBUG_DATA_PROTOCOL_VER == 1
			debug_frame_ctrl.send_data  = udsf_spi_send_data;
			debug_frame_ctrl.send_frame = udsf_spi_send_data;
			#else
			debug_frame_ctrl.send_data  = udsf_spi_send_data;
			#endif
			
		#else
			#if DEBUG_DATA_PROTOCOL_VER > 1
			
			debug_frame_ctrl.send_data  = udsf_uart_send_data_trans;	
			debug_frame_ctrl.send_frame = udsf_uart_send_data;
			#elif DEBUG_DATA_PROTOCOL_VER == 1
			debug_frame_ctrl.send_data  = udsf_uart_send_data;
			debug_frame_ctrl.send_frame = udsf_uart_send_data;
			#else
			debug_frame_ctrl.send_data  = udsf_uart_send_data;
			#endif
		}
	#endif
	
	#endif

	/*客制化数据输出*/
	#ifdef CUSTOM_DATA_ENABLE
	struct frame_struct custom_frame_ctrl;
	{
		int temp = paramRSV->frame_interval;
		if( temp > 127*10 ){
			custom_frame_ctrl.frame_info.interval_10_100_ms = temp/100 + 0x80;
		}else{
			custom_frame_ctrl.frame_info.interval_10_100_ms = temp/10 ;
		}
		
		custom_frame_ctrl.Proto_MVersion = CUSTOM_DATA_PROTOCOL_VER;
		#if CUSTOM_DATA_INTERFACE == 1
			#if CUSTOM_DATA_PROTOCOL_VER > 1
			custom_frame_ctrl.send_data  = udsf_spi_send_data_trans;
			custom_frame_ctrl.send_frame = udsf_spi_send_data;
			#elif CUSTOM_DATA_PROTOCOL_VER == 1
			custom_frame_ctrl.send_data  = udsf_spi_send_data;
			custom_frame_ctrl.send_frame = udsf_spi_send_data;
			#else
			custom_frame_ctrl.send_data  = udsf_spi_send_data;
			#endif
			
		#else
			#if CUSTOM_DATA_PROTOCOL_VER > 1
			custom_frame_ctrl.send_data  = udsf_uart_send_data_trans;	
			custom_frame_ctrl.send_frame = udsf_uart_send_data;
			#elif CUSTOM_DATA_PROTOCOL_VER == 1
			custom_frame_ctrl.send_data  = udsf_uart_send_data;
			custom_frame_ctrl.send_frame = udsf_uart_send_data;
			#else
			custom_frame_ctrl.send_data  = udsf_uart_send_data;
			#endif
		#endif
	}
	#endif


	
	
	LOG_SEND_STRING(LOG_LEVEL_DEBUG,"udf07 callback\n");

	while(1){
		 
		#if ( DEMO_INNER_UDF_SWITCH==1 )
		if( paramDataPrep->switch_flag == 0 ){
		#else
		{
		#endif
			WDT->STR = 0x1;     //FEED DOG

			#if defined(CUSTOM_DATA_ENABLE)
			custom_frame_ctrl.frame_info.draw_id = 1;
			#endif
			#if defined(DEBUG_DATA_ENABLE)
			debug_frame_ctrl.frame_info.draw_id = 1;
			#endif
			
			#if 1 && (TEST_MODE == 10) // 寄存器查看
			LOG_SEND_U32_BASE16(LOG_LEVEL_EMERG,1,&paramANA_Venus->ana1.ana_cfg0,3,"ana1 ","\r\n");
			LOG_SEND_U32_BASE16(LOG_LEVEL_EMERG,1,&paramANA_Venus->ana2.ana_cfg0,3,"ana2 ","\r\n");
			LOG_SEND_U32_BASE16(LOG_LEVEL_EMERG,1,&paramANA_Venus->ana3.ana_cfg0,3,"ana3 ","\r\n");
			LOG_SEND_U32_BASE16(LOG_LEVEL_EMERG,1,&paramANA_Venus->ana4.ana_cfg0,3,"ana4 ","\r\n");
			udsf_delay_ms(500);
			break;
			#endif
			
			#if 1 && (TEST_MODE == 1)
			if( DEBUG_DATA_FRAME_FILTER(sUDF_global.udf_tick) ) // 时域伪浮点
			{
				debug_frame_ctrl.frame_info.frame_class = eFRAME_TIMING_PSEUDO_FLOATING;
				debug_frame_ctrl.frame_info.samp_num = UDFDEF_ADCSAMP_NUM;
				debug_frame_ctrl.frame_info.samp_ant = UDFDEF_ANT_NUM;
				
				// test_mode==1时 无足够空间存放所有伪浮点时域数据，仅输出部分
				if( UDFDEF_ADCSAMP_NUM == 256 ){
					debug_frame_ctrl.frame_info.samp_chirp = 7;// 最多输出7
				}else{
					debug_frame_ctrl.frame_info.samp_chirp = UDFDEF_CHIRP_NUM - 2; // 最多输出28
				}

				debug_frame_ctrl.frame_info.draw_name = eDRAW_FRAME;
				debug_frame_ctrl.frame_info.draw_name_id = eDRAW_ANTALL;
				debug_frame_ctrl.frame_info.draw_opt = UDFDEF_CHIRP_SUM_NUM;
				
				debug_frame_ctrl.pDataSrc = (uint8_t*)(UDFDEF_ADDR_ANT2_FFT1D);// test_mode==1 借用ANT2_FFT1D地址
				udsf_data_sendx(0,&debug_frame_ctrl,-1,1,1);
				udsf_delay_ms(200);
				break;
			}
			#endif

			#if 1 && (TEST_MODE == 2) // fft1d
			for( int i = 0;i<2;i++ )
			{
				if( DEBUG_DATA_ANT_FILTER(i+1) && DEBUG_DATA_FRAME_FILTER(sUDF_global.udf_tick) )
				{
					debug_frame_ctrl.frame_info.frame_class = eFRAME_FFT1D_PSEUDO_FLOATING;
					debug_frame_ctrl.frame_info.samp_num = UDFDEF_RANGE_USE;
					debug_frame_ctrl.frame_info.samp_ant = 1;
					debug_frame_ctrl.frame_info.samp_chirp = UDFDEF_CHIRP_NUM;
					debug_frame_ctrl.frame_info.draw_name = eDRAW_FFT1D;
					debug_frame_ctrl.frame_info.draw_opt = 0;

					if( i == 0 ){
						debug_frame_ctrl.pDataSrc = (uint8_t*)(UDFDEF_ADDR_ANT1_FFT1D);
						debug_frame_ctrl.frame_info.draw_name_id = eDRAW_ANT1;
					}else{
						debug_frame_ctrl.pDataSrc = (uint8_t*)(UDFDEF_ADDR_ANT2_FFT1D);
						debug_frame_ctrl.frame_info.draw_name_id = eDRAW_ANT2;
					}
					udsf_data_sendx(0,&debug_frame_ctrl,-1,1,1);
				}
			}
			#endif
			
			#if 1 && ((TEST_MODE == 3) || (TEST_MODE == 6)) 
			#if   (TEST_MODE == 3) 
			if( DEBUG_DATA_ANT_FILTER(2) && DEBUG_DATA_FRAME_FILTER(sUDF_global.udf_tick) )
			#elif (TEST_MODE == 6)  // fft1d mean
			if( DEBUG_DATA_ANT_FILTER(1) && DEBUG_DATA_FRAME_FILTER(sUDF_global.udf_tick) )
			#endif
			{
				debug_frame_ctrl.frame_info.frame_class = eFRAME_FFT1D_PSEUDO_FLOATING;
				debug_frame_ctrl.frame_info.samp_num = UDFDEF_RANGE_USE;
				debug_frame_ctrl.frame_info.samp_ant = 1;
				debug_frame_ctrl.frame_info.samp_chirp = 1;
				debug_frame_ctrl.frame_info.draw_name = eDRAW_FFT1D_MEAN;
				debug_frame_ctrl.frame_info.draw_opt = 0;
				
				#if (TEST_MODE == 3)
				debug_frame_ctrl.frame_info.draw_name_id = eDRAW_ANT2;
				debug_frame_ctrl.pDataSrc = (uint8_t*)(UDFDEF_ADDR_ANT2_FFT1D_MEAN);
				#else
				debug_frame_ctrl.frame_info.draw_name_id = eDRAW_ANT1;
				debug_frame_ctrl.pDataSrc = (uint8_t*)(UDFDEF_ADDR_ANT1_FFT1D_MEAN);
				#endif

				udsf_data_sendx(0,&debug_frame_ctrl,-1,1,1);
			}
			#endif
			
			#if 1 && ((TEST_MODE==4) || (TEST_MODE==7))
			#if   (TEST_MODE == 4)    // fft2d
			if( DEBUG_DATA_ANT_FILTER(2) && DEBUG_DATA_FRAME_FILTER(sUDF_global.udf_tick) )
			#elif (TEST_MODE == 7)
			if( DEBUG_DATA_ANT_FILTER(1) && DEBUG_DATA_FRAME_FILTER(sUDF_global.udf_tick) )
			#endif
			{
				debug_frame_ctrl.frame_info.frame_class = eFRAME_FFT2D_PSEUDO_FLOATING;
				debug_frame_ctrl.frame_info.samp_num = UDFDEF_RANGE_USE;
				debug_frame_ctrl.frame_info.samp_ant = 1;
				debug_frame_ctrl.frame_info.samp_chirp = UDFDEF_VEL_NUM;
				debug_frame_ctrl.frame_info.draw_name = eDRAW_FFT2D;
				debug_frame_ctrl.frame_info.draw_opt = 0;
				#if ( TEST_MODE == 4 )
				debug_frame_ctrl.pDataSrc = (uint8_t*)(UDFDEF_ADDR_ANT2_FFT2D);
				debug_frame_ctrl.frame_info.draw_name_id = eDRAW_ANT2;
				#else
				debug_frame_ctrl.pDataSrc = (uint8_t*)(UDFDEF_ADDR_ANT1_FFT2D);
				debug_frame_ctrl.frame_info.draw_name_id = eDRAW_ANT1;
				#endif
				
				udsf_data_sendx(0,&debug_frame_ctrl,-1,1,1);
			}
			#endif

			#if 1 && (TEST_MODE == 5)
			if( DEBUG_DATA_ANT_FILTER(2) && DEBUG_DATA_FRAME_FILTER(sUDF_global.udf_tick) )
			{
				debug_frame_ctrl.frame_info.frame_class = eFRAME_POINTRST_ABS;
				debug_frame_ctrl.frame_info.samp_ant = 1;
				debug_frame_ctrl.frame_info.samp_num = UDFDEF_RANGE_USE;
				debug_frame_ctrl.frame_info.samp_chirp = UDFDEF_VEL_NUM;
				debug_frame_ctrl.frame_info.draw_name = eDRAW_CFAR_RV;
				debug_frame_ctrl.frame_info.draw_name_id = eDRAW_ANT2;
				debug_frame_ctrl.frame_info.draw_opt = 0;

				STRUCT_POINTRST *frameRst = (STRUCT_POINTRST *)(paramALG->framePackAddr);
				STRUCT_TARGETPOINT *p_point_unit  = (STRUCT_TARGETPOINT *)paramFunc->uartOutputAddr;

				debug_frame_ctrl.pDataSrc = (uint8_t*)(p_point_unit);
				debug_frame_ctrl.frame_info.data_len = frameRst->targetNum*sizeof(STRUCT_TARGETPOINT);
				
				for( int i = 0;i< debug_frame_ctrl.frame_info.data_len/sizeof(STRUCT_TARGETPOINT);i++){
					p_point_unit[i].d1Idx = frameRst->target[i].d1Idx;
					p_point_unit[i].d2Idx = frameRst->target[i].d2Idx;
					p_point_unit[i].d3Idx = frameRst->target[i].d3Idx;
					p_point_unit[i].powABS = frameRst->target[i].powABS;
					
					if( p_point_unit[i].d2Idx >= UDFDEF_VEL_NUM/2 ){
						p_point_unit[i].d2Idx = p_point_unit[i].d2Idx - UDFDEF_VEL_NUM/2;
					}else{
						p_point_unit[i].d2Idx = p_point_unit[i].d2Idx + UDFDEF_VEL_NUM/2;
					}
					
					if( p_point_unit[i].d3Idx >= NUM_ANGLE/2 ){
						p_point_unit[i].d3Idx = p_point_unit[i].d3Idx - NUM_ANGLE/2;
					}else{
						p_point_unit[i].d3Idx = p_point_unit[i].d3Idx + NUM_ANGLE/2;
					}
				}

				udsf_data_sendx(0,&debug_frame_ctrl,debug_frame_ctrl.frame_info.data_len,1,1);
			}
			#endif
			
			
			{ /* led 指示灯 */
				int trigger_flag = 0;
				STRUCT_POINTRST *frameRst = (STRUCT_POINTRST *)(paramALG->framePackAddr);
//				LOG_SEND_U16_BASE16(LOG_LEVEL_EMERG,1,&frameRst->targetNum,1,"targetNum:","\n");
				#if 1 && (TEST_MODE == 0) && defined(DBSCAN_ENABLE)
				struct dbscan2 *pDBSCAN = (struct dbscan2 *)(UDFDEF_ADDR_DBSCAN_BASE);
				if( sizeof( struct dbscan) > UDFDEF_SIZE_DBSCAN_STRUCT ){
					LOG_SEND_STRING(LOG_LEVEL_EMERG,"struct dbscan too large\n");
				}
				udsf_dbscan2(pDBSCAN,paramRSV,frameRst,UDFDEF_VEL_NUM);
				
				for( int i = 0;i< pDBSCAN->dbscanClu.numCluster;i++){
					LOG_SEND_U32_BASE16(LOG_LEVEL_NOTICE,1,(uint32_t*)&pDBSCAN->dbscanClu.cluster[i].rIdxMean,1,"\r\nrIdxMean "," ");
					if( pDBSCAN->dbscanClu.cluster[i].rIdxMean <= paramRSV->trigger_range_threshold*4096 ){
						trigger_flag = 1;
						break;
					}
				}		
				LOG_SEND_U8_BASE16(LOG_LEVEL_NOTICE,&pDBSCAN->dbscanClu.numCluster,1,"\r\nnumCluster","\n");
				#else
				for( int i = 0;i<frameRst->targetNum;i++){
					if( frameRst->target[i].d1Idx <= paramRSV->trigger_range_threshold ){
						trigger_flag = 1;
						break;
					}
				}
				#endif
				
				int led_run_time = 0;
				if( !trigger_flag ){
					#if defined(DBSCAN_ENABLE)
					pDBSCAN->dbscanClu.numCluster = 0;
					#endif
					frameRst->targetNum = 0;
					led_run_time = 0;
				}else{
					led_run_time = 1;
				}

				#if (LED_TRIGGER_MODE == 0 )
				if( led_run_time == 1 ){
					if( sUDF_global.udf_tick > 0xffff ){ // 防止u32溢出，led不off。此处将udf_tick 截断为u16
						sUDF_global.udf_tick = 0;
					}
					sUDF_global.udf_tick_rcd = sUDF_global.udf_tick;
					udsf_gpio_output(LED_TRIGGER_PIN,LED_TRIGGER_ACTIVE);
					LOG_SEND_STRING(LOG_LEVEL_DEBUG,"led on\n");
				}else{

					if( sUDF_global.udf_tick - sUDF_global.udf_tick_rcd > paramRSV->led_delay_cnt ){

						LOG_SEND_STRING(LOG_LEVEL_DEBUG,"led off\n");
						udsf_gpio_output(LED_TRIGGER_PIN,!LED_TRIGGER_ACTIVE);
							
						#if ( DEMO_OUTER_UDF_SWITCH == 1 )
						LOG_SEND_STRING(LOG_LEVEL_DEBUG,"switch extern lpw-udf03\n");
						udsf_udf_switch_extern(0);
						sUDF_global.udf_switch_flag = 1;
						break;
						#endif
					}
				}
				#endif
			}
			
			#if 1 && (TEST_MODE == 0) && defined(POINTRST_ENABLE)
			STRUCT_POINTRST *frameRst = (STRUCT_POINTRST *)(paramALG->framePackAddr);
			uint8_t *packRst = (uint8_t *)paramFunc->uartOutputAddr;
			uint16_t delta_time = paramRSV->frame_interval;
			#if defined(DBSCAN_ENABLE)
			int len = udsf_pointrst_ProtoGene(packRst,&pDBSCAN->dbscanClu,frameRst,delta_time,paramFunc->numTLVs);
			#else
			int len = udsf_pointrst_ProtoGene(packRst,NULL,frameRst,delta_time,paramFunc->numTLVs&0x01,1,0);
			#endif
			#if POINTRST_INTERFACE == 1
			FUNC_DATA_SEND_t point_cloud_output = udsf_spi_send_data;
			#else
			FUNC_DATA_SEND_t point_cloud_output = udsf_uart_send_data;
			#endif
			point_cloud_output(packRst,len);
			#endif
			
			// 如还需要后续算法或应用逻辑，但UDF13/UDF03 6K空间不够使用，可打开DEMO_INNER_UDF_SWITCH 及使能UDF_01_EN、batch build勾选UDF01
			#if ( DEMO_INNER_UDF_SWITCH==1 )
			#if ( UDF_EN_13 > 0 )
			#if CODE_LOAD_ONCE==1
			paramFunc->udf13_len = sUDF_global.udf13_len;
			paramFunc->funcEn |= (1<<5); // udf crc enable 
			paramFunc->qspiMode = FLASH_INTERFACE;
			#endif			
			
			paramFunc->patchEn  |= 1<<(3-1);
			paramFunc->udf03_addr = paramFunc->udf01_addr;
			paramFunc->udf03_len  = paramFunc->udf01_len;
			//udf01 伪装成 udf03
			udsf_udf_switch(13,1,1); // 切换至UDF01继续处理数据			
			#else
			udsf_udf_switch(3,1,0);  // 切换至UDF01继续处理数据
			#endif
			
			sUDF_global.udf_switch_flag = 1;
			break;
			#endif
		}
			
		#if ( DEMO_INNER_UDF_SWITCH==1 )
		paramDataPrep->switch_flag = 0;
		#endif
			
		#if !defined(LOWPOWER_ENABLE)
		udsf_rtc_get_block(0); // wait rtc0
		LOG_SEND_STRING(LOG_LEVEL_DEBUG,"UDF07 loop,no lpw\n");
		#else

		/* sleep enter -> lrc/128 clk */
		udsf_lpw_enter();
		
		/* fake sleep */
		udsf_rtc_get_block(0); // wait rtc0
		
		/* sleep exit -> lrc/1 clock */
		udsf_lpw_exit();
				
		/* full-speed run */
		udsf_full_speed();
		
		#if (DEBUG_DATA_INTERFACE == 1) || ( POINTRST_INTERFACE == 1) || (LOG_INTERFACE == 1) || ( CUSTOM_DATA_INTERFACE == 1 )
		udsf_spi_init();
		#endif
		LOG_SEND_STRING(LOG_LEVEL_DEBUG,"udf07 loop,lpw\r\n");
		#endif
		#if !defined(UART_RECV_ENABLE)
		if (GPIO->INTSTR & (1 << 7))
		{
			WDT_RSTNOW();
			while (1);
		}
		#endif
		break;
	}
}
#endif

#endif





